﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1.IICMoudle
{
    public static class  IIC
    {
        [DllImport("lib/USBIOX.DLL")]
        private static extern UInt32 USBIO_OpenDevice(UInt32 iIndex);

        [DllImport("lib/USBIOX.DLL")]
        private static extern UInt32 USBIO_CloseDevice(UInt32 iIndex);

        [DllImport("lib/USBIOX.DLL")]
        private static extern bool USBIO_SetStream(UInt32 iIndex, UInt32 iMode);

        [DllImport("lib/USBIOX.DLL")]
        private static extern bool USBIO_StreamI2C(UInt32 iIndex, UInt32 iWriteLength, UInt32 iWriteBuffer, UInt32 iReadLength, UInt32 oReadBuffer);

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void mPCH341_NOTIFY_ROUTINE(    // 设备事件通知回调程序
           UInt32 iEventStatus);   // 设备事件和当前状态： 0=设备拔出事件，3=设备插入事件

        public const int CH341_DEVICE_ARRIVA = 3;   // 设备插入事件，已经插入
        public const int CH341_DEVICE_REMOVE_PEND = 1;   // 设备将要拔出
        public const int CH341_DEVICE_REMOVE = 0;   // 设备拔出事件，已经拔出

        [DllImport("lib/USBIOX.DLL")]
        private static extern bool USBIO_SetDeviceNotify(UInt32 iIndex, string iDeviceID, mPCH341_NOTIFY_ROUTINE iNotifyRoutine);

        private static bool _bOpened = false;

        private static readonly uint INVALID_HANDLE_VALUE = 0xFFFFFFFF;

        // IIC读写函数
        public unsafe static bool WriteRead(uint wLen, byte[] wBuffer, uint rLen, byte[] rBuffer)
        {
            if (_bOpened)
            {
                fixed (byte* wP1 = wBuffer, rP1 = rBuffer)
                {
                    byte* wP2 = wP1;
                    byte* rP2 = rP1;
                    return USBIO_StreamI2C(0, wLen, (UInt32)wP2, rLen, (UInt32)rP2);
                }
            }
            else
            {
                Console.WriteLine("Please init i2c at first!");
                return false;
            }
        }

        // 设定设备事件通知程序
        public static bool SetDeviceNotify(UInt32 iIndex, string iDeviceID, mPCH341_NOTIFY_ROUTINE iNotifyRoutine)
        {
            return USBIO_SetDeviceNotify(iIndex, iDeviceID, iNotifyRoutine);
        }

        public static bool Init()
        {
            if (!_bOpened)
            {
                uint val_Handle;
                try
                {
                    val_Handle = USBIO_OpenDevice(0);
                }
                catch
                {
                    MessageBox.Show("Please check if the file \"USBIOX.DLL\" and \"usbio.dll\" are in the ./lib directory!");
                    return false;
                }

                if (val_Handle == INVALID_HANDLE_VALUE || val_Handle == 0)
                {
                    return false;
                }

                SetIICSpeed((int)I2CConstant.IICSpeed.SPEED_20KHZ);
                _bOpened = true;
            }

            return true;
        }

        public static void SetIICSpeed(int speed)
        {
            // 设置IIC速度,speed: 0表示20Hz,1表示100Hz,
            USBIO_SetStream(0, (uint)(0x80 + speed));
        }

        public static void Close()
        {
            if (_bOpened)
            {
                USBIO_CloseDevice(0);
                _bOpened = false;
            }
        }
    }
}
